package ThreadDemo.Single;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:周次煜
 * Date: 2024-07-22
 * Time：22:56
 */


/**
 *
 * 单线程的单例懒汉模式
 * 1. 在需要一个实例化时进行实例化操作
 * 2. 通过getInstance 来返回一个创建的对象
 *
 */
public class SingleLazy {

//    在内部进行实例判断
   private static SingleLazy singleLazy = null;

    public static  SingleLazy getInstance() {

        // 判断是否需要实例化
        if (singleLazy==null) {
            singleLazy=new SingleLazy();
        }

        return singleLazy;
    }

    private   SingleLazy() {

    }

}


class   Test1 {
    public static void main(String[] args) {
        SingleLazy l1 = SingleLazy.getInstance();
        SingleLazy l2 = SingleLazy.getInstance();
        System.out.println(l1==l2);

//        SingleLazy l3 =  new SingleLazy();
    }
}


/**
 * 多线程下的单例懒汉模式
 * 存在线程安全问题
 * 解决方案
 * 1. 用synchronized 来进行加锁，保证原子性
 * 2. 外层再加一层用if 防止重复加锁，从而提高效率
 * 3. 用 volatile 来修饰 该引用，防止出现指令重排序的问题 。
 *
 */



 class SingleLazy1 {

    //    在内部进行实例判断

     // 需要用 volatile 来修饰该变量
//        解决指令重排序问题
    private static volatile SingleLazy1 singleLazy1 = null;

    public static  SingleLazy1 getInstance() {

        // 防止重复加锁
        // 提高效率
        if (singleLazy1== null) {
            // 进行加锁，构成原子
            synchronized (SingleLazy1.class) {
                // 判断是否需要实例化
                if (singleLazy1==null) {
                    singleLazy1=new SingleLazy1();
                }
            }
        }



        return singleLazy1;
    }

    private   SingleLazy1() {

    }

}


class   Test2 {

  private static   SingleLazy1 s1=null;
    private static SingleLazy1 s2=null;
    private static  SingleLazy1 s3=null;
    public static void main(String[] args) throws InterruptedException {

        // 分别进行实例化
        Thread t1= new Thread(()->{
            s1 = SingleLazy1.getInstance();
        });
        Thread t2= new Thread(()->{
            s2 = SingleLazy1.getInstance();
        });
        Thread t3= new Thread(()->{
            s3 = SingleLazy1.getInstance();
        });

        t1.start();
        t2.start();
        t3.start();

        t1.join();
        t2.join();
        t3.join();

//        判断实例化的对象是否只有唯一且相同的这一个
        System.out.println(s1==s2);
        System.out.println(s2==s3);
    }
}